package com.zte.claa.inficombo.csa.app.util;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

/**
 * json转换工具
 * <p>
 * 文件名称: JsonUtils.java
 * </p>
 * <p>
 * 文件描述: 本类描述
 * </p>
 * <p>
 * 版权所有: 版权所有(C)2001-2012
 * </p>
 * <p>
 * 公 司: 中兴通讯股份有限公司
 * </p>
 * <p>
 * 内容摘要:
 * </p>
 * <p>
 * 其他说明:
 * </p>
 * <p>
 * 完成日期：2014年3月19日
 * </p>
 * <p>
 * 修改记录0：无
 * </p>
 * 
 * @version 1.0
 * @author 
 */
public class JsonUtils {
	private final static Logger logger = LoggerFactory.getLogger(JsonUtils.class);
	static ObjectMapper objectMapper;

	/**
	 * 使用泛型方法，把json字符串转换为相应的JavaBean对象。
	 * (1)转换为普通JavaBean：readValue(json,Student.class)
	 * (2)转换为List:readValue(json,List .class).但是如果我们想把json转换为特定类型的List，比如List
	 * <Student>，就不能直接进行转换了。 因为readValue(json ,List.class)返回的其实是List
	 * <Map>类型，你不能指定readValue()的第二个参数是List< Student>.class，所以不能直接转换。
	 * 我们可以把readValue()的第二个参数传递为Student[].class.然后使用Arrays
	 * .asList();方法把得到的数组转换为特定类型的List。 (3)转换为Map：readValue(json,Map.class)
	 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们使用泛型，得到的也是泛型
	 * 
	 * @param content
	 *            要转换的JavaBean类型
	 * @param valueType
	 *            原始json字符串数据
	 * @return JavaBean对象
	 */
	public static <T> T readValue(String content, Class<T> valueType) {
		if (objectMapper == null) {
			objectMapper = getObjectMapper();
		}
		try {
			return objectMapper.readValue(content, valueType);
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage(), e);
		}

		return null;
	}
	
	private static ObjectMapper getObjectMapper(){
		ObjectMapper objectMapper = new ObjectMapper();
		//序列化的时候序列对象的所有属性  
		objectMapper.setSerializationInclusion(Include.ALWAYS);  
		//如果是空对象的时候,不抛异常,也就是对应的属性没有get方法  
		objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);  
		//反序列化的时候如果多了其他属性,不抛出异常 
		objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);  
		// 设置默认的日期格式化对象.
		SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		objectMapper.getDeserializationConfig().with(sdFormat); // .withDateFormat(sdFormat);
		return objectMapper;
	}

	/**
	 * 把JavaBean转换为json字符串 (1)普通对象转换：toJson(Student) (2)List转换：toJson(List)
	 * (3)Map转换:toJson(Map) 我们发现不管什么类型，都可以直接传入这个方法
	 * 
	 * @param object
	 *            JavaBean对象
	 * @return json字符串
	 */
	public static String toJson(Object object) {
		if (objectMapper == null) {
			objectMapper = getObjectMapper();
		}
		try {
			return objectMapper.writeValueAsString(object);
			
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage(), e);
		}
		return "";
	}

	/**
	 * 将javaBean转换成map
	 * 
	 * @param object
	 * @return
	 */
	public static HashMap<String, Object> beanToHashMap(Object object) {
		HashMap<String, Object> data = new HashMap<String, Object>();
		// 将json字符串转换成jsonObject
		try{
			JSONObject jsonObject = new JSONObject(toJson(object));
			Iterator<?> it = jsonObject.keys();
			// 遍历jsonObject数据，添加到Map对象
			while (it.hasNext()) {
				String key = String.valueOf(it.next());
				Object value = jsonObject.get(key);
				data.put(key, value);
			}
		}catch(Exception e){
			logger.error("beanToHashMap failed: "+object, e);
		}
		return data;
	}
	
	/**
	 * 将json转换成map
	 * 
	 * @param object
	 * @return
	 */
	public static HashMap<String, Object> jsonStrToHashMap(String jsonStr) {
		HashMap<String, Object> data = new HashMap<String, Object>();
		// 将json字符串转换成jsonObject
		try{
			JSONObject jsonObject = new JSONObject(jsonStr);
			Iterator<?> it = jsonObject.keys();
			// 遍历jsonObject数据，添加到Map对象
			while (it.hasNext()) {
				String key = String.valueOf(it.next());
				Object value = jsonObject.get(key);
				data.put(key, value);
			}
		}catch(Exception e){
			logger.error("jsonStrToHashMap failed:"+jsonStr, e);
		}
		return data;
	}
	
	/**
	 * 将名值对map转换为json字符串.
	 * 
	 * @param pvs
	 * @return
	 */
	public static String mapToJsonStr(Map<String, Object> pvs) {
		if(pvs == null || pvs.size() == 0){
			return "{}";
		}
		JSONObject jsonObj = new JSONObject();
		try{
			Iterator<String> it = pvs.keySet().iterator();
			while(it.hasNext()){
				String key = it.next();
				Object val = pvs.get(key);
				jsonObj.put(key, val);
			}
		}catch(Exception e){
			logger.error("mapToJsonStr failed", e);
		}
		return jsonObj.toString();
	}
	
	/**
	 * 
	 * @param json
	 * @param attrName
	 * @param defValue
	 * @return
	 */
	public static String getJsonAttrVal(JSONObject json, String attrName, String defValue){
		String ret = defValue;
		try{
			ret = json.get(attrName).toString();
			if(ret == null || ret.equalsIgnoreCase("null") || ret.trim().equals("")){
				ret = defValue;
			}
		}catch(Exception e){
			logger.warn("getJsonAttrVal faield: "+json+", attr="+attrName+", err="+e.getMessage());
			ret = defValue;
		}
		return ret;
	}
	
	/**
	 * 
	 * @param json
	 * @param attrName
	 * @param defValue
	 * @return
	 */
	public static JSONObject getSubObject(JSONObject json, String attrName){
		JSONObject ret = null;
		try{
			ret = json.getJSONObject(attrName);
		}catch(Exception e){
			logger.warn("getSubObject faield: "+json+", attr="+attrName+", err="+e.getMessage());
		}
		return ret;
	}
	
	/**
	 * 
	 * @param jsonInString
	 * @return
	 */
    public static boolean isJSONValid(String jsonInString ) {
        try {
            final ObjectMapper mapper = new ObjectMapper();
            mapper.readTree(jsonInString);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

}
